/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.shared.model;

import javax.xml.bind.annotation.XmlType;

import com.google.common.annotations.GwtCompatible;
import com.google.gson.annotations.Expose;
import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.AnnotationTypeElementDoc;

/**
 * Implementation of {@link AnnotationDesc}
 *
 * @author Chad Retz
 */
@XmlType(name = "annotationDesc")
@GwtCompatible(serializable = true)
@SuppressWarnings("serial")
public class AnnotationDescImpl extends JavadocNgEntity implements AnnotationDesc {

    //exposed fields
    
    @Expose
    private String annotationType;
    
    @Expose
    private ElementValuePairImpl[] elementValues;
    
    //non-exposed fields
    
    private transient AnnotationTypeDocImpl annotationTypeLoaded;
    
    //AnnotationDesc interface impl
    
    @Override
    public AnnotationTypeDocImpl annotationType() {
        if (annotationTypeLoaded == null) {
            annotationTypeLoaded = (AnnotationTypeDocImpl) 
                    getContext().getClassDoc(annotationType);
        }
        return annotationTypeLoaded;
    }
    
    @Override
    public ElementValuePairImpl[] elementValues() {
        return elementValues;
    }
    
    //other accessors
    
    public String getAnnotationType() {
        return annotationType;
    }
    
    public void setAnnotationType(String annotationType) {
        this.annotationType = annotationType;
    }
    
    public void setElementValues(ElementValuePairImpl[] elementValues) {
        this.elementValues = elementValues;
    }
    
    @XmlType(name = "elementValuePair")
    public class ElementValuePairImpl implements ElementValuePair {
        
        //exposed fields
        
        @Expose
        private String element;
        
        @Expose
        private AnnotationValueImpl value;
        
        //non-exposed fields
        
        private transient AnnotationTypeElementDocImpl elementLoaded;
        
        //ElementValuePair interface impl
        
        @Override
        public AnnotationTypeElementDoc element() {
            if (elementLoaded == null) {
                for (AnnotationTypeElementDocImpl doc : annotationType().elements()) {
                    if (element.equals(doc.name())) {
                        elementLoaded = doc;
                        break;
                    }
                }
            }
            return elementLoaded;
        }
        
        @Override
        public AnnotationValueImpl value() {
            return value;
        }
        
        //other accessors
        
        public String getElement() {
            return element;
        }
        
        public void setElement(String element) {
            this.element = element;
        }
        
        public void setValue(AnnotationValueImpl value) {
            this.value = value;
        }
    }
}
